/* eslint-disable no-prototype-builtins */

/*
 * 表单工具类
 * 主要针对表单json进行处理 设置表单的必填 只读 可写权限
 * default: 与父代相同
 * edit: 可写
 * required: 必填
 * readonly: 只读
 * hidden: 隐藏
 * collapse: 展开
 * checkable: 勾选
 *
 */
export function setFormContentByPrivilege (content = {}, privilegeList = [], readonly) {
  // 表单的所有内部组件列表
  const list = content.list
  // 以权限的 resourceId 为纬度的map 可以用来知道哪些组件有权限需要设置
  const privilegeMap = {}
  privilegeList.forEach(item => {
    if (!privilegeMap[item.resourceId]) {
      privilegeMap[item.resourceId] = []
    }
    privilegeMap[item.resourceId].push(item)
  })

  // 记录当前表单中各个ui控件所具有的权限 以及权限的 优先级
  const uiPrivilegeMap = {}

  // 递归遍历整个表单的json
  listFormItem(list, null, uiPrivilegeMap, (uiCtl, parent, itemList, map) => {
    const key = uiCtl.key
    if (!uiCtl.options) {
      uiCtl.options = {}
    }
    if (!uiCtl.options.privilege) {
      // 默认具有最小只读权限
      uiCtl.options.privilege = {
        edit: 0
      }
      if (readonly) {
        uiCtl.options.privilege = {
          readonly: 999999
        }
        if (uiCtl.options.hasOwnProperty('clearable')) {
          if (uiCtl.desc === '发证信息.核发机关') {
            console.log('xxx', uiCtl)
          }
          uiCtl.options.clearable = false
        }
      }
      // 当前表单本身勾选了禁用 则设置禁用优先级为最高
      if (uiCtl.options.disabled) {
        uiCtl.options.privilege = {
          readonly: 999999
        }
      }
      setUIReadonly(uiCtl, null, uiCtl.options.privilege, false)
    }

    const uiPrivilege = uiCtl.options.privilege
    const privilegeList = privilegeMap[key]
    // 当前表单组件具有相关权限配置
    if (privilegeList) {
      privilegeList.forEach(privilege => {
        // 如果存在必填权限 那就赋予相同优先级的可写权限
        if (privilege.operate === 'required' && !uiPrivilege.hasOwnProperty('edit')) {
          uiPrivilege.edit = privilege.override
        }
        if (!uiPrivilege.hasOwnProperty(privilege.operate)) {
          uiPrivilege[privilege.operate] = privilege.override ?? 1
        } else {
          const override = privilege.override ?? 1
          if (override > uiPrivilege[privilege.operate]) {
            uiPrivilege[privilege.operate] = override
          }
        }
      })
    }
    if (parent) {
      const parentPrivilege = parent.options.privilege
      Object.keys(parentPrivilege).forEach(key => {
        if (uiPrivilege[key]) {
          if (uiPrivilege[key] < parentPrivilege[key]) {
            uiPrivilege[key] = parentPrivilege[key]
          }
        } else {
          uiPrivilege[key] = parentPrivilege[key]
        }
      })
    }

    if (privilegeList) {
      privilegeList.forEach(privilege => {
        // 当前组件只读
        if (privilege.operate === 'readonly') {
          setUIReadonly(uiCtl, parent, privilege, false)
        }
        if (privilege.operate === 'edit') {
          setUIEdit(uiCtl, parent, privilege, false)
        }
        if (privilege.operate === 'hidden') {
          setUIHidden(uiCtl, parent, privilege, false)
        }
        if (privilege.operate === 'required') {
          setUIRequired(uiCtl, parent, privilege, false)
        }
      })
    }
    if (parent) {
      // ======== 处理必填逻辑 ========
      const parentOpt = parent.options
      if (parentOpt.privilege) {
        const parentPrivilege = parentOpt.privilege
        if (parentPrivilege.hasOwnProperty('readonly')) {
          setUIReadonly(uiCtl, parent, parentPrivilege, true)
        }
        if (parentPrivilege.hasOwnProperty('edit')) {
          setUIEdit(uiCtl, parent, parentPrivilege, true)
        }
        if (parentPrivilege.hasOwnProperty('required')) {
          setUIRequired(uiCtl, parent, parentPrivilege, false)
        }
      }
    }
  })
}

/**
 * 设置当前表单组件为只读
 * 若该表单的父节点为可写权限 且其权值高于只读
 * 则当前组件的只读权限不生效
 * @param uiCtl 当前UI控件
 * @param parent 父UI控件
 * @param privilege 权限信息
 * @param fromParent 权限设置是否来自父组件
 */
function setUIReadonly (uiCtl = {}, parent, privilege = {}, fromParent) {
  const editOver = uiCtl.options.privilege.edit ?? -1
  const readonlyOver = uiCtl.options.privilege.readonly ?? -1
  if (!parent) {
    if (readonlyOver > editOver) {
      uiCtl.options.disabled = true
    }
    return
  }
  const parentPrivilege = parent.options.privilege
  if (parentPrivilege.hasOwnProperty('edit') && !fromParent) {
    // 父组件可写权值低 依然只读
    if (parentPrivilege.edit < readonlyOver) {
      if (readonlyOver > editOver) {
        uiCtl.options.disabled = true
      }
    }
  } else {
    // 父组件无可写权值 组件只读
    if (readonlyOver > editOver) {
      uiCtl.options.disabled = true
    }
  }
}

function setUIEdit (uiCtl = {}, parent = {}, privilege = {}, fromParent) {
  const editOver = uiCtl.options.privilege.edit ?? -1
  const readonlyOver = uiCtl.options.privilege.readonly ?? -1
  if (!parent) {
    if (editOver > readonlyOver) {
      uiCtl.options.disabled = false
    }
    return
  }
  const parentPrivilege = parent.options.privilege
  if (parentPrivilege.hasOwnProperty('readonly') && !fromParent) {
    // 父组件只读权值低 依然可写
    if (parentPrivilege.readonly < editOver) {
      if (editOver > readonlyOver) {
        uiCtl.options.disabled = false
      }
    }
  } else {
    // 父组件无只读权值 组件可写
    if (editOver > readonlyOver) {
      uiCtl.options.disabled = false
    }
  }
}

function setUIHidden (uiCtl = {}, parent = {}, privilege = {}, fromParent) {
  const editOver = uiCtl.options.privilege.edit ?? -1
  const hiddenOver = uiCtl.options.privilege.readonly ?? 1
  if (hiddenOver > editOver) {
    uiCtl.options.hidden = true
  }
}

function setUIRequired (uiCtl = {}, parent = {}, privilege = {}, fromParent) {
  if (uiCtl.type === 'text') {
    uiCtl.options.showRequiredMark = true
  }
  if (uiCtl.rules && uiCtl.rules.length > 0) {
    uiCtl.rules[0].required = true
  }
}

export function listFormItem (itemList = [], parent = {}, map = {}, callback) {
  itemList.forEach(item => {
    callback(item, parent, itemList, map)
    if (item.trs && item.trs.length > 0) {
      listFormItem(item.trs, item, map, callback)
    }
    if (item.tds && item.tds.length > 0) {
      listFormItem(item.tds, item, map, callback)
    }
    if (item.columns && item.columns.length > 0) {
      listFormItem(item.columns, item, map, callback)
    }
    if (item.list && item.list.length > 0) {
      listFormItem(item.list, item, map, callback)
    }
  })
}

export function getDataByErrorEmpty (e, owner, dataPre) {
  const errorItems = []
  const gsErrorItems = []
  const keys = Object.keys(e)
  keys.forEach(function (item) {
    if (e[item].errors && e[item].errors.length > 0) {
      const errs = e[item].errors
      if (errs && errs.length > 0) {
        errs.forEach(err => {
          if (owner._.isArray(err) && err.length > 0) {
            err.forEach(it => {
              it.parentModel = e[item].parentModel
              errorItems.push(it)
            })
          } else {
            errorItems.push(err)
          }
        })
      }
    }
  })
  errorItems.forEach(function (item, index) {
    gsErrorItems.push(item)
  })

  const data = owner._.cloneDeep(dataPre)
  gsErrorItems.forEach(function (item, index) {
    const list = item.field.split('.')
    // 普通表数据处理
    if (list.length === 2) {
      const table = list[0]
      const field = list[1]
      if (data[table]) {
        data[table][field] = null
      }
    }
    // 数组处理
    if (list.length === 3) {
      const table = item.parentModel
      const index = list[1]
      const field = list[2]
      if (data[table] && data[table][index]) {
        data[table][index][field] = null
      }
    }
    // data[item.split('.')[0]][item.split('.')[1]] = null
  })
  return data
}
